
package com.hlkj.pay.app.merchant.ext.impl.helipay.ext;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.*;

import com.hlkj.pay.dto.order.PayOrderFundDto;
import com.hlkj.pay.infrastructure.model.order.OrderFundDetailDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderQueryContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelRefundPayOrderContext;
import com.hlkj.pay.app.merchant.ext.impl.helipay.constant.HeliPayConstant;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.HeliPayAppChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.HeliPayConfig;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.res.HeliPayOrderAccountRes;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.res.HeliPayOrderCommonRes;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.res.HeliPayOrderQueryRes;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.res.HeliPayRefundOrderQueryRes;
import com.hlkj.pay.app.merchant.ext.impl.helipay.handler.HeliPayMerchantCommonParamsHandle;
import com.hlkj.pay.controller.common.ConfigController;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.enums.PayOrderEnums;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.order.PayOrderDO;
import com.hlkj.pay.infrastructure.model.order.OrderFundDO;
import com.hlkj.pay.infrastructure.model.order.RefundOrderDO;
import com.hlkj.pay.util.DateUtils;
import com.hlkj.pay.util.MerchantUtils;
import com.hlkj.pay.vo.order.req.OrderAccount;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 合利宝 正扫 反扫 通用处理
 * 
 * @author HlpayTeam
 * @date 2024/10/11 16:22
 */
@Slf4j
@Repository
@RequiredArgsConstructor
public class HeliPaySceneCommonPayOrder {

    @Autowired
    private HeliPayMerchantCommonParamsHandle heliPayMerchantCommonParamsHandle;
    @Autowired
    private ConfigController configController;

    /**
     * 合利宝查询支付订单
     * 
     * @param channelPayOrderQueryContext
     */
    public void commonQueryChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        // 配置转换
        CommonResult<HeliPayConfig> commonResult = heliPayMerchantCommonParamsHandle.heliPayConfig(channelPayOrderQueryContext.getProviderChannelConfigDO(),
                channelPayOrderQueryContext.isTest());
        HeliPayConfig heliPayConfig = commonResult.getData();

        PayOrderDO payOrderDO = channelPayOrderQueryContext.getPayOrderDO();
        HeliPayAppChannelParams heliPayAppChannelParams = heliPayAppChannelParams(channelPayOrderQueryContext.getMerchantAppChannelDO());
        try {
            String payUrl = heliPayMerchantCommonParamsHandle.payUrl(channelPayOrderQueryContext.isTest());
            LinkedHashMap<String, String> params = new LinkedHashMap<>();
            params.put("P1_bizType", "AppPayQuery");
            params.put("P2_orderId", payOrderDO.getPayOrderNo());
            params.put("P3_customerNumber", heliPayAppChannelParams.getMerchantNo());
            log.info("合利宝 订单查询 请求参数:{}", JsonUtils.toJsonString(params));
            CommonResult<String> resultResult = heliPayMerchantCommonParamsHandle.heliPayOrderRequest(payUrl, heliPayConfig, params, null);
            log.info("合利宝 订单查询 返回参数:{}", JsonUtils.toJsonString(resultResult));
            if (!resultResult.isSuccess()) {
                channelPayOrderQueryContext.setRemark("合利宝订单查询请求失败,失败信息" + resultResult.getMsg());
                channelPayOrderQueryContext.setProcessStatus(Boolean.FALSE);
                return;
            }
            String response = resultResult.getData();
            HeliPayOrderQueryRes heliPayOrderQueryRes = JsonUtils.parseObject(response, HeliPayOrderQueryRes.class);

            PayOrderDO updartePayOrderDO = new PayOrderDO();
            channelPayOrderQueryContext.setUpdartePayOrderDO(updartePayOrderDO);
            if (HeliPayConstant.REQUEST_SUCCESS.equals(heliPayOrderQueryRes.getRt2_retCode())) {
                switch (heliPayOrderQueryRes.getRt7_orderStatus()) {
                    case "INIT":
                    case "DOING":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.PAYING.getCode());
                        updartePayOrderDO.setBankMsg("");
                        break;
                    case "SUCCESS":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.SUCCESS.getCode());
                        updartePayOrderDO.setBankMsg("");
                        break;
                    case "FAIL":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.FAIL.getCode());
                        break;
                    case "CLOSE":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.CLOSE.getCode());
                        break;
                    case "CANCEL":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.CANCEL.getCode());
                        break;

                }
                if (StringUtils.hasText(heliPayOrderQueryRes.getRt13_orderCompleteDate())) {
                    try {
                        updartePayOrderDO.setSuccessTime(DateUtils.shanghaiDate(heliPayOrderQueryRes.getRt13_orderCompleteDate(), "yyyy-MM-dd HH:mm:ss"));
                    }
                    catch (Exception e) {
                        log.error("合利宝订单查询返回 时间格式化错误 dateTime:{},message:{}", heliPayOrderQueryRes.getRt13_orderCompleteDate(), e.getMessage());
                    }
                }
                updartePayOrderDO.setInsOrderNo(heliPayOrderQueryRes.getRt18_outTransactionOrderId());
                updartePayOrderDO.setChannelOrderId(heliPayOrderQueryRes.getRt6_serialNumber());
                if (StringUtils.hasText(heliPayOrderQueryRes.getChannelSettlementAmount())) {
                    updartePayOrderDO.setSettlementAmount(MerchantUtils.stringToBigDecimal(heliPayOrderQueryRes.getChannelSettlementAmount()));
                }
                if (StringUtils.hasText(heliPayOrderQueryRes.getRt25_paymentAmount())) {
                    updartePayOrderDO.setPayAmount(MerchantUtils.stringToBigDecimal(heliPayOrderQueryRes.getRt25_paymentAmount()));
                }
                else {
                    updartePayOrderDO.setPayAmount(payOrderDO.getAmount());
                }
                if (StringUtils.hasText(heliPayOrderQueryRes.getRt11_openId())) {
                    updartePayOrderDO.setUserId(heliPayOrderQueryRes.getRt11_openId());
                }
                else {
                    updartePayOrderDO.setUserId(heliPayOrderQueryRes.getRt20_subOpenId());
                }
                if (StringUtils.hasText(heliPayOrderQueryRes.getRuleJson())) {
                    List<HeliPayOrderAccountRes> heliPayOrderAccountRes = JsonUtils.parseArray(heliPayOrderQueryRes.getRuleJson(), HeliPayOrderAccountRes.class);
                    List<OrderFundDetailDO> orderFunds=new ArrayList<>();
                    heliPayOrderAccountRes.stream().forEach(heliPayOrderAccountRes1 -> {
                        OrderFundDetailDO orderAccount = new OrderFundDetailDO();
                        orderAccount.setAmount(MerchantUtils.stringToBigDecimal(heliPayOrderAccountRes1.getSplitBillAmount()));
                        orderAccount.setAccountNo(heliPayOrderAccountRes1.getSplitBillMerchantNo());
                        orderAccount.setOutOrderNo(heliPayOrderAccountRes1.getSplitBillOrderNum());
                        orderAccount.setBatchNo(heliPayOrderAccountRes1.getSplitBillRequestNo());
                        orderAccount.setFailReason(heliPayOrderAccountRes1.getSplitBillRetMsg());
                        if (StringUtils.hasText(heliPayOrderAccountRes1.getSplitBillOrderStatus())) {
                            switch (heliPayOrderAccountRes1.getSplitBillOrderStatus()) {
                                case "SUCCESS":
                                    orderAccount.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.SUCCESS.getCode());
                                    break;
                                case "FAILED":
                                    orderAccount.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FAIL.getCode());
                                    break;
                                default:
                                    orderAccount.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FUNDING.getCode());
                            }
                        }
                        orderFunds.add(orderAccount);
                    });
                    channelPayOrderQueryContext.setOrderFunds(orderFunds);
                }
            }
            else {
                String respDesc = heliPayOrderQueryRes.getRt3_retMsg();
                updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.FAIL.getCode());
                if (StringUtils.hasText(respDesc)) {
                    updartePayOrderDO.setBankMsg(respDesc);
                }
                else {
                    channelPayOrderQueryContext.setRemark("合利宝提交支付订单查询返回错误信息为空,错误码为:" + heliPayOrderQueryRes.getRt2_retCode());
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("合利宝提交条码支付请求失败 message:{}", e.getMessage(), e);
            channelPayOrderQueryContext.setRemark("合利宝提交条码支付请求失败,失败信息" + e.getMessage());
            channelPayOrderQueryContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantAccessQueryContext.setAccessStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.APPROVE_REFUSE);
        }
    }

    /**
     * 合利宝关闭订单
     * 
     * @param channelPayOrderQueryContext
     */
    public void commonCloseChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        // 配置转换
        CommonResult<HeliPayConfig> commonResult = heliPayMerchantCommonParamsHandle.heliPayConfig(channelPayOrderQueryContext.getProviderChannelConfigDO(),
                channelPayOrderQueryContext.isTest());
        HeliPayConfig heliPayConfig = commonResult.getData();

        PayOrderDO payOrderDO = channelPayOrderQueryContext.getPayOrderDO();
        HeliPayAppChannelParams heliPayAppChannelParams = heliPayAppChannelParams(channelPayOrderQueryContext.getMerchantAppChannelDO());
        try {
            String payUrl = heliPayMerchantCommonParamsHandle.payUrl(channelPayOrderQueryContext.isTest());
            LinkedHashMap<String, Object> params = new LinkedHashMap<>();
            params.put("P1_bizType", "AppPayClose");
            params.put("P2_orderId", payOrderDO.getPayOrderNo());
            params.put("P3_customerNumber", heliPayAppChannelParams.getMerchantNo());
            log.info("合利宝 订单关闭 请求参数:{}", JsonUtils.toJsonString(params));
            CommonResult<String> resultResult = heliPayMerchantCommonParamsHandle.heliPayOrderRequest(payUrl, heliPayConfig, params, null);
            log.info("合利宝 订单关闭 返回参数:{}", JsonUtils.toJsonString(resultResult));
            if (!resultResult.isSuccess()) {
                channelPayOrderQueryContext.setRemark("合利宝订单关闭请求失败,失败信息" + resultResult.getMsg());
                channelPayOrderQueryContext.setProcessStatus(Boolean.FALSE);
                return;
            }
            String response = resultResult.getData();
            HeliPayOrderCommonRes heliPayOrderCommonRes = JsonUtils.parseObject(response, HeliPayOrderCommonRes.class);

            if (HeliPayConstant.REQUEST_SUCCESS.equals(heliPayOrderCommonRes.getRt2_retCode())) {
                PayOrderDO updartePayOrderDO = new PayOrderDO();
                updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.CLOSE.getCode());
                channelPayOrderQueryContext.setUpdartePayOrderDO(updartePayOrderDO);
            }
            else {
                String respDesc = heliPayOrderCommonRes.getRt3_retMsg();
                channelPayOrderQueryContext.setProcessStatus(Boolean.FALSE);
                if (StringUtils.hasText(respDesc)) {
                    channelPayOrderQueryContext.setRemark(respDesc);
                }
                else {
                    channelPayOrderQueryContext.setRemark("合利宝订单关闭返回错误信息为空,错误码为:" + heliPayOrderCommonRes.getRt2_retCode());
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("合利宝关闭支付订单请求失败 message:{}", e.getMessage(), e);
            channelPayOrderQueryContext.setRemark("合利宝关闭支付订单请求失败,失败信息" + e.getMessage());
            channelPayOrderQueryContext.setProcessStatus(Boolean.FALSE);
        }
    }

    /**
     * 合利宝查询关闭订单状态
     * 
     * @param channelPayOrderQueryContext
     */
    public void commonQueryChannelClosePayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        // 合利宝无此接口
        PayOrderDO updartePayOrderDO = new PayOrderDO();
        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.CLOSE.getCode());
        channelPayOrderQueryContext.setUpdartePayOrderDO(updartePayOrderDO);
    }

    /**
     * 合利宝订单退款
     * 
     * @param channelRefundPayOrderContext
     */
    public void commonRefundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        // 配置转换
        CommonResult<HeliPayConfig> commonResult = heliPayMerchantCommonParamsHandle.heliPayConfig(channelRefundPayOrderContext.getProviderChannelConfigDO(),
                channelRefundPayOrderContext.isTest());
        HeliPayConfig heliPayConfig = commonResult.getData();

        PayOrderDO payOrderDO = channelRefundPayOrderContext.getPayOrderDO();
        RefundOrderDO refundOrderDO = channelRefundPayOrderContext.getRefundOrderDO();
        HeliPayAppChannelParams heliPayAppChannelParams = heliPayAppChannelParams(channelRefundPayOrderContext.getMerchantAppChannelDO());
        try {
            String payUrl = heliPayMerchantCommonParamsHandle.payUrl(channelRefundPayOrderContext.isTest());
            LinkedHashMap<String, Object> signFieldMap = new LinkedHashMap<>();
            Map<String, Object> noSignFieldMap = new HashMap<>();
            signFieldMap.put("P1_bizType", "AppPayRefund");
            signFieldMap.put("P2_orderId", payOrderDO.getPayOrderNo());
            signFieldMap.put("P3_customerNumber", heliPayAppChannelParams.getMerchantNo());
            signFieldMap.put("P4_refundOrderId", refundOrderDO.getRefundOrderNo());
            signFieldMap.put("P5_amount", MerchantUtils.bigDecimalToString2(refundOrderDO.getRefundAmount()));
            signFieldMap.put("P6_callbackUrl", channelRefundPayOrderContext.getNotifyUrl());
            noSignFieldMap.put("P7_desc", refundOrderDO.getRefundReason());
            log.info("合利宝 订单退款 请求参数:{}", JsonUtils.toJsonString(signFieldMap));
            CommonResult<String> resultResult = heliPayMerchantCommonParamsHandle.heliPayOrderRequest(payUrl, heliPayConfig, signFieldMap, noSignFieldMap);
            log.info("合利宝 订单退款 返回参数:{}", JsonUtils.toJsonString(resultResult));
            if (!resultResult.isSuccess()) {
                channelRefundPayOrderContext.setRemark("合利宝订单关闭请求失败,失败信息" + resultResult.getMsg());
                channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
                return;
            }
            String response = resultResult.getData();
            HeliPayOrderCommonRes heliPayOrderCommonRes = JsonUtils.parseObject(response, HeliPayOrderCommonRes.class);

            if (HeliPayConstant.REQUEST_SUCCESS.equals(heliPayOrderCommonRes.getRt2_retCode()) || HeliPayConstant.DOING_SUCCESS.equals(heliPayOrderCommonRes.getRt2_retCode())) {
                RefundOrderDO updateRefundOrderDO = new RefundOrderDO();
                updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.REFUNDING.getCode());
                channelRefundPayOrderContext.setUpdateRefundOrderDO(updateRefundOrderDO);
            }
            else {
                String respDesc = heliPayOrderCommonRes.getRt3_retMsg();
                channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
                if (StringUtils.hasText(respDesc)) {
                    channelRefundPayOrderContext.setRemark(respDesc);
                }
                else {
                    channelRefundPayOrderContext.setRemark("合利宝提交退款订单返回错误信息为空,错误码为:" + heliPayOrderCommonRes.getRt2_retCode());
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("合利宝提交退款订单请求失败 message:{}", e.getMessage(), e);
            channelRefundPayOrderContext.setRemark("合利宝提交退款订单请求失败,失败信息" + e.getMessage());
            channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
        }
    }

    /**
     * 合利宝订单退款状态查询
     * 
     * @param channelRefundPayOrderContext
     */
    public void commonQueryRefundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        // 配置转换
        CommonResult<HeliPayConfig> commonResult = heliPayMerchantCommonParamsHandle.heliPayConfig(channelRefundPayOrderContext.getProviderChannelConfigDO(),
                channelRefundPayOrderContext.isTest());
        HeliPayConfig heliPayConfig = commonResult.getData();

        PayOrderDO payOrderDO = channelRefundPayOrderContext.getPayOrderDO();
        RefundOrderDO refundOrderDO = channelRefundPayOrderContext.getRefundOrderDO();
        HeliPayAppChannelParams heliPayAppChannelParams = heliPayAppChannelParams(channelRefundPayOrderContext.getMerchantAppChannelDO());
        try {
            String payUrl = heliPayMerchantCommonParamsHandle.payUrl(channelRefundPayOrderContext.isTest());
            LinkedHashMap<String, Object> params = new LinkedHashMap<>();
            params.put("P1_bizType", "AppPayRefundQuery");
            params.put("P2_refundOrderId", refundOrderDO.getRefundOrderNo());
            params.put("P3_customerNumber", heliPayAppChannelParams.getMerchantNo());
            log.info("合利宝 退款查询 请求参数:{}", JsonUtils.toJsonString(params));
            CommonResult<String> resultResult = heliPayMerchantCommonParamsHandle.heliPayOrderRequest(payUrl, heliPayConfig, params, null);
            log.info("合利宝 退款查询 返回参数:{}", JsonUtils.toJsonString(resultResult));
            if (!resultResult.isSuccess()) {
                channelRefundPayOrderContext.setRemark("合利宝退款查询请求失败,失败信息" + resultResult.getMsg());
                channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
                return;
            }
            String response = resultResult.getData();
            HeliPayRefundOrderQueryRes heliPayRefundOrderQueryRes = JsonUtils.parseObject(response, HeliPayRefundOrderQueryRes.class);

            RefundOrderDO updateRefundOrderDO = new RefundOrderDO();
            channelRefundPayOrderContext.setUpdateRefundOrderDO(updateRefundOrderDO);
            if (HeliPayConstant.REQUEST_SUCCESS.equals(heliPayRefundOrderQueryRes.getRt2_retCode())) {
                switch (heliPayRefundOrderQueryRes.getRt8_orderStatus()) {
                    case "FAIL":
                        updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.FAIL.getCode());
                        updateRefundOrderDO.setBankMsg(heliPayRefundOrderQueryRes.getRt10_desc());
                        break;
                    case "PART_REFUND":
                        break;
                    case "SUCCESS":
                        updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.REFUND.getCode());
                        if (StringUtils.hasText(heliPayRefundOrderQueryRes.getRt11_refundOrderCompleteDate())) {
                            try {
                                updateRefundOrderDO.setSuccessTime(DateUtils.shanghaiDate(heliPayRefundOrderQueryRes.getRt11_refundOrderCompleteDate(), "yyyy-MM-dd HH:mm:ss"));
                            }
                            catch (Exception e) {
                                log.error("合利宝退款订单查询返回 时间格式化错误 dateTime:{},message:{}", heliPayRefundOrderQueryRes.getRt11_refundOrderCompleteDate(), e.getMessage());
                            }
                        }
                        break;
                    default:
                        updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.REFUNDING.getCode());
                }
                if (StringUtils.hasText(heliPayRefundOrderQueryRes.getRefundCashAmount())) {
                    updateRefundOrderDO.setActualRefundAmount(MerchantUtils.stringToBigDecimal(heliPayRefundOrderQueryRes.getRefundCashAmount()));
                }
            }
            else {
                String respDesc = heliPayRefundOrderQueryRes.getRt3_retMsg();
                updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.FAIL.getCode());
                if (StringUtils.hasText(respDesc)) {
                    updateRefundOrderDO.setBankMsg(respDesc);
                }
                else {
                    channelRefundPayOrderContext.setRemark("合利宝退款订单查询返回错误信息为空,错误码为:" + heliPayRefundOrderQueryRes.getRt2_retCode());
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("合利宝退款订单查询请求失败 message:{}", e.getMessage(), e);
            channelRefundPayOrderContext.setRemark("合利宝提交条码支付请求失败,失败信息" + e.getMessage());
            channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantAccessQueryContext.setAccessStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.APPROVE_REFUSE);
        }
    }

    public HeliPayAppChannelParams heliPayAppChannelParams(MerchantAppChannelDO merchantAppChannelDO) {
        return JsonUtils.parseObject(merchantAppChannelDO.getAppConfigJson(), HeliPayAppChannelParams.class);
    }

    public String accountRuleJson(List<PayOrderFundDto> accounts) {
        if (CollectionUtils.isEmpty(accounts)) {
            return JsonUtils.toJsonString(Collections.emptyList());
        }
        List<Map> maps = new ArrayList<>();
        accounts.stream().forEach(account -> {
            Map<String, Object> params = new HashMap<>();
            params.put("splitBillMerchantNo", account.getAccountNo());
            params.put("splitBillAmount", account.getAmount());
            maps.add(params);
        });
        return JsonUtils.toJsonString(maps);
    }

    public String expireMinute(Long time, PayEnums.PAY_TYPE payType) {
        switch (payType) {
            case ALIPAY:
                if (time == null) {
                    return 30 + "m";
                }
                return (time - System.currentTimeMillis()) / 1000 / 60 + "m";
            default:
            case WECHAT:
            case UNION_APY:
                if (time == null) {
                    return 30 * 60 + "";
                }
                return (time - System.currentTimeMillis()) / 1000 + "";
        }
    }
}
